package hyl.base.net.udp;
/**
 * 基于核心包udp的扩展
 * 
 * 数据包必须小于指定大小
 * 
 * 连续接收的udp 需要放入队列<br>
 * 并且数据需要按照特有格式封装
 * @author 37798955@qq.com
 *
 */

import java.net.DatagramPacket;
import java.net.SocketAddress;

import hyl.base.kv.cache.QueueObject;
import hyl.core.net.MyUdp;
import hyl.core.run.IDo1;
import hyl.core.run.IFilter;
import hyl.core.run.MyRun;

public class UdpService {

	MyUdp _udp;
	QueueObject<UdpData> _queue = null;
	public int getServPort() {
		return _udp.getBindPort();
	}
	/**
	 * 默认缓存大小是8k
	 * @param 本地服务端口
	 */
	public UdpService(int 本地服务端口) {
		_queue = new QueueObject<>("./cache/udproute/" + 本地服务端口, null, 0);
		_udp = new MyUdp(本地服务端口);	
		listen() ;
	}


	public void close() {
		curThread.interrupt();
	}
	public void send(String 对方ip, int 对方服务端口, byte 类型, byte[] 发送数据) {
		UdpData ud = new UdpData();
		ud.setB类型(类型).setData(发送数据);
		MyUdp.send(对方ip, 对方服务端口, ud.getSendBytes());
	}

	public void send(SocketAddress 对方socket, byte 类型, byte[] 发送数据) {
		UdpData ud = new UdpData();
		ud.setB类型(类型).setData(发送数据);
		MyUdp.send(对方socket, ud.getSendBytes());
	}
	// 如果没有回调函数,就打印数据,一般用于测试
	public void print() {
		IFilter<DatagramPacket> call = new IFilter<DatagramPacket>() {
			@Override
			public boolean where(DatagramPacket obj) {
				UdpData ud = new UdpData();
				ud.setIpPort(obj.getAddress().getHostAddress(), obj.getPort());
				ud.receiveData(obj.getData(), obj.getLength()).getData();
				System.out.println(ud.toString());
				return false;
			}
		};
		_udp.receive(call);
	}

	public UdpData pull() {
		return _queue.pull();
	}

	public void pull(IDo1<UdpData> 回调) {
		while (Thread.currentThread().isAlive()) {
			UdpData data = _queue.pull();
			回调.run(data);
		}
	}
	Thread curThread ;
	//开始监听
	public void listen() {
		IFilter<DatagramPacket> call = new IFilter<DatagramPacket>() {
			@Override
			public boolean where(DatagramPacket obj) {
				UdpData ud = new UdpData();
				ud.setIpPort(obj.getAddress().getHostAddress(), obj.getPort());
				ud.receiveData(obj.getData(), obj.getLength());
				_queue.push(ud);
				// 回调函数.run(ud);
				return false;
			}
		};
		curThread = MyRun.start用户线程(() -> _udp.receive(call));
		
	}

}
